#
#  Python code to talk to a APSX RFID Module
#
#  Not a complete set of functions but...
#
#  17 March 2009   TCM       - Created
#

from time import sleep
import serial

ser = None

PresetValue = 0xffff
Polynomial = 0x8408

def read_UID() :
    "Read a UID or None if not exactly 12 bytes"
    ser.write('\xfa')
    s = ser.read(12)
    #ser.flushInput()
    #ser.flushOutput()
    if len(s) == 12 :
        return s
    return None

def Stay_Quiet(tag) :
    #ser.flushInput()
    #ser.flushOutput()
    "Tell a tag to shut up"
    #Transmitter OFF
    #ser.write('\xf7')
    #sleep(0.5)
    #Transmitter ON
    ser.write('\xf8')
    sleep(0.05)
    if tag == 1 :
        #Tag A: eee98a12000104e0 \ e17c
        ser.write('\x0D\x00\x23\x02\xee\xe9\x8a\x12\x00\x01\x04\xe0\xc7\x3f')
    elif tag == 2 :
        #Tag B: f16f8a12000104e0 \ fb48
        ser.write('\x0D\x00\x23\x02\xF1\x6F\x8a\x12\x00\x01\x04\xe0\xDD\x0B')
    elif tag == 3 :
        #Tag C: 85f18a12000104e0 \ a963
        ser.write('\x0D\x00\x23\x02\x85\xf1\x8a\x12\x00\x01\x04\xe0\x8f\x20')
    elif tag == 4 :
        #Tag D: 8def8a12000104e0 \ fd7d
        ser.write('\x0D\x00\x23\x02\x8D\xEF\x8a\x12\x00\x01\x04\xe0\xDB\x3E')
    elif tag == 5 :
        #Tag E: c3fe8a12000104e0 \ 1d02
        ser.write('\x0D\x00\x23\x02\xC3\xFE\x8a\x12\x00\x01\x04\xe0\x3B\x41')
    elif tag == 6 :
        #Tag F: feb48a12000104e0 \ 197b
        ser.write('\x0D\x00\x23\x02\xFE\xB4\x8a\x12\x00\x01\x04\xe0\x3f\x38')
    elif tag == 7 :
        #Tag G: 48b28a12000104e0 \ 0f18
        ser.write('\x0D\x00\x23\x02\x48\xB2\x8a\x12\x00\x01\x04\xe0\x29\x5B')
    elif tag == 8 :
        #Tag H: 09d88a12000104e0 \ 93b1
        ser.write('\x0D\x00\x23\x02\x09\xD8\x8a\x12\x00\x01\x04\xe0\xB5\xF2')
    else :
        return 0

    #crc('\x00\x03\x04\x64\x85\xf1\x8a\x12\x00\x01\x04\xe0')
    sleep(0.05)
    #s = ser.read(12)
    #print s
    #s = ser.write('\x06\x0C\x27\x01\x00\x2A\x50')
    #s = ser.read(12)
#    if len(s) == 12 :
    #return s
#    return None

def Select() :
    ser.flushInput()
    ser.flushOutput()
    "Select a tag"
    #Tag B: f16f8a12000104e0//fb48
    #Tag C: 85f18a12000104e//0a963
    #Tag H: 09d88a12000104e0//93b1
    #ser.write('\x0E\x0C\x23\x25\x00\xF1\x6F\x8a\x12\x00\x01\x04\xe0\x60\x08')#Tag B
    ser.write('\x0E\x0C\x23\x25\x00\x85\xf1\x8a\x12\x00\x01\x04\xe0\x32\x23')#Tag C
    #ser.write('\x0E\x0C\x23\x25\x00\x09\xD8\x8a\x12\x00\x01\x04\xe0\x08\xF1')#Tag H
    sleep(0.5)
    s = ser.read()
#    s = read_UID()
#    ser.write('\xfa')
#    if len(s) == 12 :
    return s
#    return None

def red_LED(on) :
    if on :
        ser.write('\xfd')
    else :
        ser.write('\xfc')
    sleep(.1)


def green_LED(on) :
    if on :
        ser.write('\xff')
    else :
        ser.write('\xfe')
    sleep(.1)


#a = '\x27\x01\x00'
#print crc(a)
#print 'should be 2a 50 (%d, %d)' %(0x2a,0x50)

def rfid_open(port) :
    "call to open the serial port"

    global ser
    if ser :
        if ser.isOpen() :
            ser.close()
    ser = serial.Serial(port, 19200, timeout=1) 
    print ser.portstr

#s = read_UID()
#if s :

def hexer(s) :
    "return a hex string"

    h = ''
    for c in s :
        h += '0x%02x ' % ord(c)
    return h

def crc(DataBytes) :
    "APSX ISO 15693 CRC-16"

    CRCValue = PresetValue
    for b in DataBytes :
        CRCValue = CRCValue ^ ord(b)

        for j in range(0,8) :
            if CRCValue & 1 :
                CRCValue = (CRCValue>>1) ^ Polynomial
            else :
                CRCValue >>= 1
               
    CRCValue = ~CRCValue - 65536
    CRCValue &= 0xffff
    CRCLSB = CRCValue % 256
    CRCMSB = CRCValue >> 8

    return (hex(CRCLSB), hex(CRCMSB))

def concat_command(UID) :
    command = [UID]
    crcval = crc(UID)
    print crcval
    command = [UID]
    for ch in crcval:
        hv = str(ch).replace('0x', '')
        if len(hv) == 1:
            hv = '0'+hv
        command.append('0x'+hv)
    
    return reduce(lambda x,y:x+y, command)

def continuous_monitor() :
    count = 0
    while count != 10:

        # get a button
        #
        b = read_UID()
        sleep(.1)
	count += 1

        if b :
            green_LED(True)
            print 'got a button: %s' % hexer(b)
            return b

            while b :
                sleep(1)
                b = read_UID()

            green_LED(False)

        else :
            red_LED(True)
            sleep(.1)
            red_LED(False)
            sleep(.9)
    
    return None

	


rfid_open(0)

# let's  blink some
#
for i in range(1,5) :
    red_LED(True)
    sleep(.1)
    green_LED(True)
    sleep(.1)
    red_LED(False)
    sleep(.1)
    green_LED(False)
    sleep(.1)




#red_LED(True)
#green_LED(True)
#red_LED(False)
#green_LED(False)

#ser.close()
